package com.talkyun.utils.para;

import com.thoughtworks.paranamer.CachingParanamer;
import com.thoughtworks.paranamer.Paranamer;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ParaNamer {
    public class Param {
        String name;
        Type type;

        Param(String name, Type type) {
            this.name = name;
            this.type = type;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Type getType() {
            return type;
        }

        public void setType(Type type) {
            this.type = type;
        }
    }

    private Map<String, List<Param>> k2p = new ConcurrentHashMap<String, List<Param>>();
    private Paranamer paranamer = new MixedParaNamer();

    public List<Param> getParaList(Method method) {
        try {
            return doParaList(method);
        } catch (Throwable t) {
            throw new RuntimeException("Run maven paranamer plugin first!", t);
        }
    }

    private List<Param> doParaList(Method method) {
        String key = method.getDeclaringClass().getName() + ":" + method.getName() + ":" + method.getGenericParameterTypes().length;
        List<Param> list = k2p.get(key);
        if (list == null) {
            list = new ArrayList<Param>();
            Type[] types = method.getGenericParameterTypes();
            String[] names = paranamer.lookupParameterNames(method);
            for (int i = 0; i < types.length; i++) {
                list.add(new Param(names[i], types[i]));
            }
            k2p.put(key, list);
        }
        return list;
    }
}